package org.ligson.fwc.core.util;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.ligson.fwc.api.util.JsonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.UnsupportedEncodingException;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HttpClientUtil {
    private CloseableHttpClient client;
    private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);

    public HttpClientUtil(File p12, String mchId) throws Exception {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyStore.load(new FileInputStream(p12), mchId.toCharArray());
        final SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchId.toCharArray()).build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
        client = HttpClientBuilder.create().setSSLSocketFactory(sslsf).build();
    }

    private void init() {
        client = HttpClientBuilder.create().build();
    }

    public HttpClientUtil() {
        init();
    }

    public HttpClientUtil(CloseableHttpClient client) {
        this.client = client;
    }

    public String doGet(String url, Map<String, String> params, List<BasicHeader> headers) {
        StringBuilder builder = new StringBuilder(url);
        if (!url.contains("?")) {
            builder.append("?");
        }
        if (MapUtils.isNotEmpty(params)) {
            params.forEach((k, v) -> builder.append("&").append(k).append("=").append(v));
        }
        HttpGet httpGet = new HttpGet(builder.toString());
        return doRequest(httpGet, headers);
    }

    public String doGet(String url, Map<String, String> params) {
        return doGet(url, params, null);
    }

    private String doRequest(HttpUriRequest request, List<BasicHeader> headers) {
        try {
            logger.debug("开始访问接口:{}", request.getURI());
            if (CollectionUtils.isNotEmpty(headers)) {
                for (BasicHeader header : headers) {
                    logger.debug("header:{}={}", header.getName(), header.getValue());
                    request.setHeader(header);
                }
            }
            CloseableHttpResponse respose = client.execute(request);
            logger.debug("访问接口:{}返回状态码:{}", request.getURI(), respose.getStatusLine().getStatusCode());
            String text = EntityUtils.toString(respose.getEntity(), "UTF-8");
            logger.debug("访问接口:{}返回数据:{}", request.getURI(), text);
            return text;
        } catch (Exception e) {
            logger.error("访问接口:{}错误:{}", request.getURI(), e.getMessage(), e);
            return null;
        }
    }

    public String doPost(String url, Map<String, String> params, List<BasicHeader> headers) {
        List<NameValuePair> pairs = new ArrayList<>();
        if (MapUtils.isNotEmpty(params)) {
            params.forEach((k, v) -> pairs.add(new BasicNameValuePair(k, v)));
        }
        logger.debug("开始访问接口:{},参数:{}", url, JsonUtil.toJson(params));
        UrlEncodedFormEntity entity = null;
        try {
            entity = new UrlEncodedFormEntity(pairs, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            logger.error("访问接口:{}错误:{}", url, e.getMessage(), e);
            return null;
        }
        return doPost(url, entity, headers);

    }

    public String doPost(String url, HttpEntity entity, List<BasicHeader> headers) {
        HttpPost httpPost = new HttpPost(url);
        try {
            httpPost.setEntity(entity);
            return doRequest(httpPost, headers);
        } catch (Exception e) {
            logger.error("访问接口:{}错误:{}", url, e.getMessage(), e);
            return null;
        }
    }

    public String doPost(String url, String reqStr) {
        logger.debug("开始访问接口:{},参数:{}", url, reqStr);
        StringEntity stringEntity = new StringEntity(reqStr, "UTF-8");
        return doPost(url, stringEntity, null);
    }

    public String doPost(String url, Map<String, String> params) {
        return doPost(url, params, null);
    }
}
